package com.example.voucher.config;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import com.example.voucher.config.bo.SubjectMappingConfigBO;
import com.example.voucher.config.bo.SubjectReducingConfigBO;
import com.example.voucher.config.bo.TenantMirrorItemBO;
import com.example.voucher.config.third.TenantThirdAccountBO;

@Component
@ConfigurationProperties(prefix = com.example.voucher.common.VoucherConstant.TENANT_MIRROR_CONFIG_PREFIX)
public class TenantMirrorConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(TenantMirrorConfig.class);

    private List<TenantMirrorItemBO> mirrorList;

    @Autowired
    private ThirdAccountRegister accountRegister;
    @Autowired
    private SubjectConfigRegister subjectRegister;

    public List<TenantMirrorItemBO> getMirrorList() {
        return mirrorList;
    }

    public void setMirrorList(List<TenantMirrorItemBO> mirrorList) {
        this.mirrorList = mirrorList;
    }

    public String getMirror(String tenantCode) {
        if (CollectionUtils.isNotEmpty(getMirrorList())) {
            for (TenantMirrorItemBO mirrorItem : mirrorList) {
                if (tenantCode.equals(mirrorItem.getCopyTo())) {
                    return mirrorItem.getCopyFrom();
                }
            }
        }
        return null;
    }

    public TenantThirdAccountBO getAccountConfig(String tenantCode) {
        TenantThirdAccountBO bo = null;
        Exception srcExcp = null;
        try {
            bo = accountRegister.getAccountConfig(tenantCode);
        } catch (Exception e) {
            srcExcp = e;
        }
        if (bo == null) {
            String mirrorTenantCode = getMirror(tenantCode);
            if (StringUtils.isNotBlank(mirrorTenantCode)) {
                LOGGER.warn("找不到租户=【{}】推送第三方凭证账户相关的配置，模拟租户【{}】", tenantCode, mirrorTenantCode);
                bo = accountRegister.getAccountConfig(mirrorTenantCode);
            }
        }
        if (bo == null && null != srcExcp) {
            throw new RuntimeException(srcExcp);
        }
        return bo;
    }

    public List<String> getSubjectConfig(String tenantCode, String scenarioCode) {
        List<String> list = null;
        Exception srcExcp = null;
        try {
            list = subjectRegister.getSubjectConfig(tenantCode, scenarioCode);
        } catch (Exception e) {
            srcExcp = e;
        }
        if (CollectionUtils.isEmpty(list)) {
            String mirrorTenantCode = getMirror(tenantCode);
            if (StringUtils.isNotBlank(mirrorTenantCode)) {
                LOGGER.warn("找不到租户=【{}】场景=【{}】需要生成哪些科目相关的配置，模拟租户【{}】", tenantCode, scenarioCode, mirrorTenantCode);
                list = subjectRegister.getSubjectConfig(mirrorTenantCode, scenarioCode);
            }
        }
        if (CollectionUtils.isEmpty(list) && null != srcExcp) {
            throw new RuntimeException(srcExcp);
        }
        return list;
    }

    public Map<String, SubjectReducingConfigBO> getReducingConfig(String tenantCode, String scenarioCode) {
        Map<String, SubjectReducingConfigBO> map = null;
        Exception srcExcp = null;
        try {
            map = subjectRegister.getReducingConfig(tenantCode, scenarioCode);
        } catch (Exception e) {
            srcExcp = e;
        }
        if (MapUtils.isEmpty(map)) {
            String mirrorTenantCode = getMirror(tenantCode);
            if (StringUtils.isNotBlank(mirrorTenantCode)) {
                LOGGER.warn("找不到租户=【{}】场景=【{}】科目分组汇总相关的配置，模拟租户【{}】", tenantCode, scenarioCode, mirrorTenantCode);
                map = subjectRegister.getReducingConfig(mirrorTenantCode, scenarioCode);
            }
        }
        if (MapUtils.isEmpty(map) && null != srcExcp) {
            throw new RuntimeException(srcExcp);
        }
        return map;
    }

    public Map<String, SubjectMappingConfigBO> getMappingConfig(String tenantCode, String scenarioCode) {
        Map<String, SubjectMappingConfigBO> map = null;
        Exception srcExcp = null;
        try {
            map = subjectRegister.getMappingConfig(tenantCode, scenarioCode);
        } catch (Exception e) {
            srcExcp = e;
        }
        if (MapUtils.isEmpty(map)) {
            String mirrorTenantCode = getMirror(tenantCode);
            if (StringUtils.isNotBlank(mirrorTenantCode)) {
                LOGGER.warn("找不到租户=【{}】场景=【{}】科目字段映射相关的配置，模拟租户【{}】", tenantCode, scenarioCode, mirrorTenantCode);
                map = subjectRegister.getMappingConfig(mirrorTenantCode, scenarioCode);
            }
        }
        if (MapUtils.isEmpty(map) && null != srcExcp) {
            throw new RuntimeException(srcExcp);
        }
        return map;
    }

}
